﻿using DBUtil.SqlSegment;
using DotNetCommon.Extensions;
using System.Collections.Generic;
using System.Linq;

namespace DBUtil.Provider.SqlServer.SqlSegment;

/// <summary>
/// 数据库字符串运算符
/// </summary>
public class SqlServerStringSqlSegment(DBAccess db) : StringSqlSegment(db)
{
    /// <inheritdoc/>
    public override string GetLength(string sqlSeg, bool null2Zero = false)
    {
        if (null2Zero) return $"len(isnull({sqlSeg},''))";
        else return $"len({sqlSeg})";
    }
    /// <inheritdoc/>
    public override string Trim(string sqlSeg) => db.IsSqlServerVersion2017Compatible() ? $"trim({sqlSeg})" : $"ltrim(rtrim({sqlSeg}))";
    ///// <summary>
    ///// 左右两侧trim指定字符串, 这个功能sqlserver支持比较复杂<br/>
    ///// 参考: <seealso href="https://blog.csdn.net/u010476739/article/details/151458692"/><br/>
    ///// 如果考虑是否支持大小写就...(事实上, 一般我们在翻译 "".Contains("") 也没有在乎过 db 和 c# 在大小写之间的差异)
    ///// </summary>
    //public string Trim(string sqlSeg, string patSeg) => $"trim(both {patSeg} from {sqlSeg})";
    /// <inheritdoc/>
    public override string LeftTrim(string colName) => $"ltrim({colName})";
    ///// <summary>
    ///// 左侧trim指定字符串, 这个功能sqlserver支持比较复杂<br/>
    ///// 参考: <seealso href="https://blog.csdn.net/u010476739/article/details/151458692"/><br/>
    ///// 如果考虑是否支持大小写就...(事实上, 一般我们在翻译 "".Contains("") 也没有在乎过 db 和 c# 在大小写之间的差异)
    ///// </summary>
    //public string LeftTrim(string sqlSeg, string patSeg) => $"trim(leading {patSeg} from {sqlSeg})";
    /// <inheritdoc/>
    public override string RightTrim(string sqlSeg) => $"rtrim({sqlSeg})";
    ///// <summary>
    ///// 右侧trim指定字符串, 这个功能sqlserver支持比较复杂<br/>
    ///// 参考: <seealso href="https://blog.csdn.net/u010476739/article/details/151458692"/><br/>
    ///// 如果考虑是否支持大小写就...(事实上, 一般我们在翻译 "".Contains("") 也没有在乎过 db 和 c# 在大小写之间的差异)
    ///// </summary>
    //public string RightTrim(string sqlSeg, string patSeg) => $"trim(trailing {patSeg} from {sqlSeg})";
    /// <inheritdoc/>
    public override string Upper(string sqlSeg) => $"upper({sqlSeg})";
    /// <inheritdoc/>
    public override string Lower(string sqlSeg) => $"lower({sqlSeg})";
    /// <inheritdoc/>
    public override string ReplaceAll(string inputSqlSeg, string oldStrSqlSeg, string newStrSqlSeg) => $"replace({inputSqlSeg},'{oldStrSqlSeg}','{newStrSqlSeg}')";
    /// <inheritdoc/>
    public override string SplitFirst(string inputSqlSeg, string patternSqlSeg) => $"substring({inputSqlSeg},0,charindex({patternSqlSeg},{inputSqlSeg},0))";
    /// <inheritdoc/>
    public override string SplitLast(string inputSqlSeg, string patternSqlSeg) => $"reverse(substring(reverse({inputSqlSeg}),0,charindex({patternSqlSeg},reverse({inputSqlSeg}),0)))";
    /// <inheritdoc/>
    public override string Add(string inputSqlSeg, string input2SqlSeg)
        => db.IsSqlServerVersion2012Compatible() ? $"concat({inputSqlSeg},{input2SqlSeg})" : $"isnull({inputSqlSeg},'')+isnull({input2SqlSeg},'')";

    /// <inheritdoc/>
    public override string AddMulti(IEnumerable<string> inputSqlSegs, bool canReturnNull = false)
        => canReturnNull ? inputSqlSegs.ToStringSeparated("+") : db.IsSqlServerVersion2012Compatible() ? $"concat({inputSqlSegs.ToStringSeparated(",")})" : inputSqlSegs.Select(i => $"isnull({i},'')").ToStringSeparated("+");

    /// <inheritdoc/>
    public override string SubString(string input, int start, int len) => $"substring({input},{start + 1},{len})";

    /// <inheritdoc/>
    public override string IndexOf(string inputSqlSeg, string patternSqlSeg, bool ignoreCase = true)
        => $"charindex({patternSqlSeg},{inputSqlSeg}){(ignoreCase ? "" : " collate sql_latin1_general_cp1_cs_as")}-1";
    /// <inheritdoc/>
    public override string IsNullOrEmpty(string inputSqlSeg)
    {
        return $"({inputSqlSeg} is null or {inputSqlSeg} = '')";
    }
    /// <inheritdoc/>
    public override string IsNullOrWhiteSpace(string inputSqlSeg)
    {
        return $"({inputSqlSeg} is null or ltrim({inputSqlSeg}) = '')";
    }
}
